package org.gap.wizards.world;

import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import org.gap.wizards.Drawable;
import org.gap.wizards.Start;
import org.gap.wizards.utils.Persistence;
import org.gap.wizards.views.ViewPlatform;
import org.gap.wizards.views.ViewPlatform.Color;

public class Wilderness extends CommonLocation implements Location {
	private static final int LONG_RANGE_VIEW = 13;
	private static final int CLOSE_RANGE_VIEW = 7;
	private List<Point> trees;

	public Wilderness() {
		super();
		trees = new ArrayList<Point>();
	}

	@Override
	public void move(Movement move) {
		tryMove(move.adjustLocation(pc.getLocation()));
	}

	@Override
	public boolean canMoveTo(Point moveTo) {
		if (isBlockedByCreatures(moveTo)) { return false; }
		if (!super.canMoveTo(moveTo)) { return false; }
		return !intersectsBuildings(moveTo) && isBetween(moveTo.x, 0, width - 1) && isBetween(moveTo.y, 0, height - 1);
	}
	
	@Override
	public boolean isBlocked(Point point) {
		return super.isBlocked(point) || trees.contains(point);
	}

	private boolean isBetween(int desiredLocation, int lowerBound, int upperBound) {
		return desiredLocation >= lowerBound && desiredLocation <= upperBound;
	}

	@Override
	protected boolean shouldDraw(Drawable each) {
		if (System.getProperty("show.all") != null) {
			return true;
		}
		return distanceFromCoordinate(each.getX(), each.getY()) < LONG_RANGE_VIEW;
	}

	@Override
	protected void drawPermanentFixtures(ViewPlatform console) {
		drawFieldOfViewAroundPlayer(console);
		for (Point each : trees) {
			console.print(each.x, each.y, Color.GREEN, 'T');
		}
		super.drawPermanentFixtures(console);
	}

	private void drawFieldOfViewAroundPlayer(ViewPlatform console) {
		for (int x = 0; x < Start.SCREEN_WIDTH; x++) {
			for (int y = 0; y < Start.SCREEN_HEIGHT; y++) {
				paintDiamondShapeFielfOfView(console, x, y);
			}
		}
	}

	void paintDiamondShapeFielfOfView(ViewPlatform console, int x, int y) {
		int distance = distanceFromCoordinate(x, y);
		if (distance < CLOSE_RANGE_VIEW) {
			console.print(x, y, Color.WHITE, '.');
		} else if (distance < LONG_RANGE_VIEW) {
			console.print(x, y, Color.GREEN, (char) (803));
		}
	}

	public void plantTree(int x, int y) {
		trees.add(new Point(x, y));
	}
	
	@Override
	public void addTransition(MapTransition mapTransition) {
		trees.remove(new Point(mapTransition.getX(), mapTransition.getY()));
		super.addTransition(mapTransition);
	}

	@Override
	public void addClosedSpace(int x, int y, int width, int height, Point door) {
		Rectangle building = new Rectangle(x, y, width, height);
		List<Point> intersectingBuilding = new LinkedList<Point>();
		for (Point each : trees) {
			if (building.contains(each)) {
				intersectingBuilding.add(each);
			}
		}
		trees.removeAll(intersectingBuilding);
		super.addClosedSpace(x, y, width, height, door);
	}

	@Override
	public void persist(Persistence persistence) {
		persistence.set("trees", trees.toArray(new Point[trees.size()]));
		super.persist(persistence);
	}

	@Override
	public void load(Persistence persistence) {
		trees.addAll(Arrays.asList(persistence.getPoints("trees")));
		super.load(persistence);
	}

	@Override
	public boolean equals(Object obj) {
		if (obj.getClass().equals(Wilderness.class)) {
			Wilderness other = (Wilderness) obj;
			return trees.size() == other.trees.size() && super.equals(obj);
		}
		return false;
	}
}
